package converters

import (
	protos "goim-pro/api/protos/salty"
	"goim-pro/internal/app/constants"
	"goim-pro/internal/app/models"
	"goim-pro/pkg/utils"
	"strings"
)

// convert proto to entity for contact remark profile
func ConvertProto2EntityForRemarkProfile(profile *protos.ContactRemark) models.RemarkProfile {
	remarkProfile := models.RemarkProfile{
		RemarkName:  profile.RemarkName,
		Description: profile.Description,
	}
	if profile.Telephones != nil && len(profile.Telephones) > 0 {
		remarkProfile.Telephone = strings.Join(profile.Telephones, ",")
	} else {
		remarkProfile.Telephone = ""
	}
	if profile.Tags != nil && len(profile.Tags) > 0 {
		remarkProfile.Tags = strings.Join(profile.Tags, ",")
	} else {
		remarkProfile.Tags = ""
	}
	return remarkProfile
}

func ConvertEntity2ProtoForContacts(contacts ...models.Contact) (protoContacts []*protos.ContactProfile) {
	protoContacts = make([]*protos.ContactProfile, len(contacts))
	for i, contact := range contacts {
		protoContacts[i] = ConvertContactEntity2Proto(contact)
	}
	return protoContacts
}

func ConvertContactEntity2Proto(contact models.Contact) (protoContact *protos.ContactProfile) {
	userProfile := contact.User
	protoContact = &protos.ContactProfile{
		UserProfile: &protos.UserProfile{
			UserId:      contact.ContactId,
			UserNumber:  userProfile.UserNumber,
			Telephone:   contact.Telephone,
			Email:       userProfile.Email,
			Nickname:    userProfile.Nickname,
			Avatar:      userProfile.Avatar,
			Description: userProfile.Description,
			Location:    userProfile.Location,
			Birthday:    userProfile.Birthday,
			UpdateTime:  utils.ParseTimeToTimestamp(userProfile.UpdatedAt),
			CreateTime:  utils.ParseTimeToTimestamp(userProfile.CreatedAt),
			Sex:         consts.UserSexStringMapping[userProfile.Sex],
		},
		RemarkInfo: &protos.ContactRemark{
			RemarkName:     contact.RemarkName,
			Description:    contact.Description,
			LastUpdateTime: utils.ParseTimeToTimestamp(contact.UpdatedAt),
		},
		AcceptContactTime: utils.ParseTimeToTimestamp(contact.CreatedAt),
	}
	if !utils.IsEmptyStrings(strings.Trim(contact.RemarkName, "")) {
		protoContact.SortId = utils.GetStringLetters(contact.RemarkName)
	} else {
		protoContact.SortId = utils.GetStringLetters(userProfile.Nickname)
	}
	if !utils.IsEmptyStrings(strings.Trim(contact.Telephone, "")) {
		protoContact.RemarkInfo.Telephones = strings.Split(contact.Telephone, ",")
	}
	if !utils.IsEmptyStrings(strings.Trim(contact.Tags, "")) {
		protoContact.RemarkInfo.Tags = strings.Split(contact.Tags, ",")
	}
	return protoContact
}

func ConvertEntity2ProtoForContactRelations(relationGroup map[string][]models.ContactOperation, userId string) (pbRelations []*protos.ContactOperationRelation) {
	pbRelations = make([]*protos.ContactOperationRelation, len(relationGroup))
	var index = 0
	for key, operation := range relationGroup {
		pbRelations[index] = &protos.ContactOperationRelation{
			RelationId: key,
			Operations: ConvertEntity2ProtoOfContactOperations(operation, userId),
			CreateTime: utils.ParseTimeToTimestamp(operation[len(operation)-1].CreatedAt),
			UpdateTime: utils.ParseTimeToTimestamp(operation[0].UpdatedAt),
		}
		index++
	}
	return pbRelations
}

func ConvertEntity2ProtoOfContactOperations(contactOperations []models.ContactOperation, userId string) (pbOperations []*protos.ContactOperation) {
	pbOperations = make([]*protos.ContactOperation, len(contactOperations))
	for i, item := range contactOperations {
		pbOperations[i] = ConvertEntity2ProtoOfContactOperation(item, getDirection(userId, item.SenderId))
	}
	return
}

func ConvertEntity2ProtoOfContactOperation(contactOperation models.ContactOperation, direction protos.ContactOperation_Direction) (pbOperation *protos.ContactOperation) {
	pbOperation = &protos.ContactOperation{
		OperationId: contactOperation.OpsId,
		RelationId:  contactOperation.RelationId,
		Reason:      contactOperation.Reason,
		CreateTime:  utils.ParseTimeToTimestamp(contactOperation.CreatedAt),
		Type:        protos.ContactOperation_Type(contactOperation.OperationType),
		Direction:   direction,
		SendUser:    ConvertEntity2ProtoForUserProfile(contactOperation.Sender),
		ReceiveUser: ConvertEntity2ProtoForUserProfile(contactOperation.Recipient),
	}
	return
}

func getDirection(userId, senderId string) protos.ContactOperation_Direction {
	if userId == senderId {
		return protos.ContactOperation_SEND
	} else {
		return protos.ContactOperation_RECEIVE
	}
}
